home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / CONFIGUR.C < prev    next >
C/C++ Source or Header  |  1991-12-07  |  19KB  |  497 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    c o n f i g u r . c                                             */
  3. /*                                                                    */
  4. /*    Support routines for UUPC/extended                              */
  5. /*                                                                    */
  6. /*    Changes Copyright 1990, 1991 (c) Andrew H. Derbyshire           */
  7. /*                                                                    */
  8. /*    History:                                                        */
  9. /*       21Nov1991 Break out of lib.c                          ahd    */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <time.h>
  16.  
  17. /*--------------------------------------------------------------------*/
  18. /*                    UUPC/extended include files                     */
  19. /*--------------------------------------------------------------------*/
  20.  
  21. #include "lib.h"
  22. #include "hlib.h"
  23.  
  24. /*--------------------------------------------------------------------*/
  25. /*                          Global variables                          */
  26. /*--------------------------------------------------------------------*/
  27.  
  28. currentfile();
  29.  
  30. boolean bflag[F_LAST];        /* Initialized to zero by compiler     */
  31.  
  32. char *aliases = NULL;
  33. char *anonymous = NULL;
  34. char *archivedir = NULL;
  35. char *confdir = NULL;
  36. char *domain = NULL;
  37. char *E_altsignature = NULL;
  38. char *E_backup = NULL;
  39. char *E_charset = NULL;
  40. char *E_editor = NULL;
  41. char *E_filesent = NULL;
  42. char *E_inmodem = NULL;
  43. char *E_mailext = NULL;
  44. char *E_pager = NULL;
  45. char *E_rmail = NULL;
  46. char *E_rnews = NULL;
  47. char *E_signature = NULL;
  48. char *E_uuxqtpath = NULL;
  49. char *fdomain = NULL;
  50. char *homedir = NULL;
  51. char *localdomain = NULL;
  52. char *mailbox = NULL;
  53. char *maildir = NULL;
  54. char *mailserv = NULL;
  55. char *name = NULL;
  56. char *newsdir = NULL;
  57. char *newsserv = NULL;
  58. char *nodename = NULL;
  59. char *organization = NULL;
  60. char *postmaster = NULL;
  61. char *pubdir = NULL;
  62. char *replyto = NULL;
  63. char *spooldir = NULL;
  64. char *tempdir = NULL;
  65. static char *dummy = NULL;
  66.  
  67. INTEGER maxhops = 20;                                       /* ahd */
  68. INTEGER PacketTimeout = 10;   /* Allow ten seconds per packet        */
  69. INTEGER PortTimeout = 0;      /* Computed default based on Packet
  70.                                  timeout                             */
  71. INTEGER MaxErr= 10;           /* Allowed errors per single packet    */
  72. INTEGER xfer_bufsize = BUFSIZ;/* Buffering used for file transfers   */
  73.  
  74.  
  75. static boolean getrcnames(char **sysp,char **usrp);
  76.  
  77. /*--------------------------------------------------------------------*/
  78. /*  The following table controls the configuration files processing   */
  79. /*--------------------------------------------------------------------*/
  80.  
  81. static CONFIGTABLE table[] = {
  82.    "aliases",       &aliases,        B_TOKEN|B_MUA,
  83.    "altsignature",  &E_altsignature, B_TOKEN|B_MUA,
  84.    "anonymouslogin",&anonymous,      B_GLOBAL|B_TOKEN|B_UUIO,
  85.    "archivedir",    &archivedir,     B_REQUIRED|B_GLOBAL|B_TOKEN|B_NEWS,
  86.    "backupext",     &E_backup,       B_TOKEN|B_MUA,
  87.    "confdir",       &confdir,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  88.    "charset",       &E_charset,      B_TOKEN|B_GLOBAL|B_SPOOL,
  89.    "domain",        &domain,         B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  90.    "editor",        &E_editor,       B_STRING|B_MUA|B_NEWS,
  91.    "filesent",      &E_filesent,     B_TOKEN|B_MUA|B_NEWS,
  92.    "folders",       &dummy,          B_TOKEN|B_MUSH ,
  93.    "fromdomain",    &fdomain,        B_GLOBAL|B_MAIL|B_NEWS|B_TOKEN,
  94.    "home",          &homedir,        B_STRING|B_REQUIRED|B_ALL,
  95.    "inmodem",       &E_inmodem,      B_GLOBAL|B_TOKEN|B_UUIO,
  96.    "localdomain",   &localdomain,    B_GLOBAL|B_TOKEN|B_MAIL,
  97.    "mailbox",       &mailbox,        B_REQUIRED|B_TOKEN|B_ALL,
  98.    "mailext",       &E_mailext,      B_TOKEN|B_MAIL,
  99.    "maildir",       &maildir,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_MAIL,
  100.    "mailserv",      &mailserv,       B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  101.    "maximumerrors", (char **) &MaxErr, B_MTA | B_INTEGER | B_GLOBAL,
  102.    "maximumhops",   (char **) &maxhops, B_MTA | B_INTEGER | B_GLOBAL,
  103.    "mushdir",       &dummy,          B_GLOBAL|B_TOKEN|B_MUSH,
  104.    "name",          &name,           B_REQUIRED|B_ALL,
  105.    "newsdir",       &newsdir,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_NEWS,
  106.    "newsserv",      &newsserv,       B_GLOBAL|B_TOKEN|B_NEWS,
  107.    "nodename",      &nodename,       B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  108.    "options",       (char **) bflag, B_ALL|B_BOOLEAN,
  109.    "organization",  &organization,   B_STRING|B_MUA|B_NEWS,
  110.    "packettimeout", (char **) &PacketTimeout, B_UUIO | B_INTEGER | B_GLOBAL,
  111.    "pager",         &E_pager,        B_STRING|B_MUA|B_NEWS,
  112.    "path",          &E_uuxqtpath,    B_STRING|B_UUIO|B_GLOBAL,
  113.    "porttimeout",   (char **) &PortTimeout,   B_UUIO | B_INTEGER | B_GLOBAL,
  114.    "postmaster",    &postmaster,     B_REQUIRED|B_GLOBAL|B_TOKEN|B_MTA,
  115.    "pubdir",        &pubdir,         B_REQUIRED|B_GLOBAL|B_TOKEN|B_SPOOL,
  116.    "replyto",       &replyto,        B_TOKEN|B_MUA|B_NEWS,
  117.    "rmail",         &E_rmail,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  118.    "rnews",         &E_rnews,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_UUIO,
  119.    "signature",     &E_signature,    B_TOKEN|B_MUA|B_NEWS,
  120.    "spooldir",      &spooldir,       B_REQUIRED|B_GLOBAL|B_TOKEN|B_SPOOL|B_NEWS,
  121.    "tempdir",       &tempdir,        B_REQUIRED|B_GLOBAL|B_TOKEN|B_ALL,
  122.    "transferbuffer", (char **) &xfer_bufsize, B_UUIO | B_INTEGER | B_GLOBAL,
  123.    nil(char)
  124. }; /* table */
  125.  
  126. /*--------------------------------------------------------------------*/
  127. /*               Boolean options shared by all programs               */
  128. /*--------------------------------------------------------------------*/
  129.  
  130. FLAGTABLE configFlags[] = {
  131.    "askcc",       F_ASKCC,       B_LOCAL,
  132.    "autoedit",    F_AUTOEDIT,    B_LOCAL,
  133.    "autoinclude", F_AUTOINCLUDE, B_LOCAL,
  134.    "autoprint",   F_AUTOPRINT,   B_LOCAL,
  135.    "autosign",    F_AUTOSIGN,    B_LOCAL,
  136.    "backup",      F_BACKUP,      B_LOCAL,
  137.    "doskey",      F_DOSKEY,      B_LOCAL,
  138.    "dot",         F_DOT,         B_LOCAL,
  139.    "expert",      F_EXPERT,      B_LOCAL,
  140.    "forwardsave", F_SAVERESENT,  B_LOCAL,
  141.    "fromsep",     F_FROMSEP,     B_LOCAL,
  142.    "pager",       F_PAGER,       B_LOCAL,
  143.    "purge",       F_PURGE,       B_LOCAL,
  144.    "save",        F_SAVE,        B_LOCAL,
  145.    "verbose",     F_VERBOSE,     B_LOCAL,
  146.  
  147.    "bang",        F_BANG,        B_GLOBAL,
  148.    "directory",   F_DIRECT,      B_GLOBAL,
  149.    "history",     F_HISTORY,     B_GLOBAL,
  150.    "kanji",       F_KANJI,       B_GLOBAL,
  151.    "monocase",    F_ONECASE,     B_GLOBAL,
  152.    "multiqueue",  F_MULTI,       B_GLOBAL,
  153.    "syslog",      F_SYSLOG,      B_GLOBAL,
  154.  
  155.    nil(char)
  156. }           ;
  157.  
  158. /*--------------------------------------------------------------------*/
  159. /*    p r o c e s s c o n f i g                                       */
  160. /*                                                                    */
  161. /*    Handle a single line of a configuration file                    */
  162. /*--------------------------------------------------------------------*/
  163.  
  164. boolean processconfig(char *buff,
  165.                   SYSMODE sysmode,
  166.                   CONFIGBITS program,
  167.                   CONFIGTABLE *table,
  168.                   FLAGTABLE *btable)
  169. {
  170.    CONFIGTABLE *tptr;
  171.    char *cp;
  172.  
  173. /*--------------------------------------------------------------------*/
  174. /*                break out the keyword from its value                */
  175. /*--------------------------------------------------------------------*/
  176.  
  177.    if ((cp = strchr(buff, '=')) == nil(char))
  178.    {
  179.       printmsg(0,"Missing equals sign after keyword \"%s\", ignored", buff);
  180.       return TRUE;
  181.    }
  182.    *cp++ = '\0';
  183.    strlwr(buff);
  184.  
  185. /*--------------------------------------------------------------------*/
  186. /*                    Scan the table for its value                    */
  187. /*--------------------------------------------------------------------*/
  188.  
  189.    for (tptr = table; tptr->sym != nil(char); tptr++)
  190.    {
  191.       boolean error = FALSE;
  192.       if (equal(buff, tptr->sym)) {
  193.         if ((tptr->bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
  194.             printmsg(0,
  195.                "User specified system parameter \"%s\" ignored.",
  196.                tptr->sym);
  197. /*--------------------------------------------------------------------*/
  198. /*                       Handle Boolean options                       */
  199. /*--------------------------------------------------------------------*/
  200.          else {
  201.             if (tptr->bits & B_BOOLEAN)
  202.                options(cp, sysmode, btable, (boolean *) tptr->loc);
  203. /*--------------------------------------------------------------------*/
  204. /*                       Handle integer values                        */
  205. /*--------------------------------------------------------------------*/
  206.             else if (tptr->bits & B_INTEGER)
  207.             {
  208.                int *value = (int *) tptr->loc;
  209.                cp = strtok(cp,WHITESPACE);
  210.                if ( equal(cp,"0"))
  211.                   *value = 0;
  212.                else {
  213.                   *value = atoi(cp);
  214.                   if ( *value == 0)
  215.                   {
  216.                      printmsg(0,
  217.                         "Unable to convert \"%s\" value \"%s\" to integer",
  218.                         buff, cp);
  219.                      error = TRUE;
  220.                   } /* if */
  221.                } /* else */
  222.             } /* else */
  223. /*--------------------------------------------------------------------*/
  224. /*                       Handle lists of tokens                       */
  225. /*--------------------------------------------------------------------*/
  226.             else if ((tptr->bits & program) && (tptr->bits & (B_LIST | B_CLIST)))
  227.             {
  228.                char **list = malloc( 50 * sizeof (*list));
  229.                char *colon;
  230.                int words;
  231.  
  232.                checkref( list );
  233.  
  234.                if (tptr->bits & B_CLIST)  /* Use colon as delimiter? */
  235.                   while ( (colon = strchr( cp , ':')) != NULL)
  236.                      *colon = ' ';     /* Make colons spaces ...           */
  237.  
  238.                words = getargs(cp, list);
  239.                if( words > 49)
  240.                   panic();
  241.  
  242.                if (words > 0)
  243.                {
  244.                   char **savelist = (char **) *(tptr->loc);
  245.  
  246.                   if (savelist != NULL)
  247.                   {
  248.                      while( *savelist != NULL)
  249.                         if (strlen(*savelist))
  250.                            free( *savelist++);
  251.                      free( *(tptr->loc) );
  252.                   }
  253.                   list = realloc( list, (words+1) * sizeof(*list));
  254.                   checkref( list );
  255.                   *(tptr->loc) = (char *) list;
  256.                   list[words] = NULL;
  257.  
  258.                   while( *list != NULL)
  259.                   {
  260.                      if (strlen(*list))
  261.                      {
  262.                         *list = strdup(*list);
  263.                         checkref( *list++ );
  264.                      }
  265.                      else
  266.                         *list++ = "";
  267.                   } /* while */
  268.                } /* if (words > 0) */
  269.                else {
  270.                   printmsg(0,"No parameters given for keyword \"%s\"",
  271.                            buff);
  272.                   error = TRUE;
  273.                   free( list );
  274.                } /* else */
  275.             } /* else if */
  276. /*--------------------------------------------------------------------*/
  277. /*                  Handle single tokens and strings                  */
  278. /*--------------------------------------------------------------------*/
  279.             else if (tptr->bits & program)
  280.             {
  281.                if (*(tptr->loc) != nil(char))
  282.                   free(*(tptr->loc));  /* free the previous one */
  283.  
  284.                while( *cp == ' ' )     /* Trim leading whitespace    */
  285.                   cp++;
  286.  
  287.                if (*cp == '\0')
  288.                {
  289.                   error = TRUE;
  290.                   printmsg(0,"No parameter given for keyword \"%s\""
  291.                            ", ignored.",
  292.                            buff);
  293.                } /* if */
  294.  
  295.                if (tptr->bits & B_TOKEN)  /* One word value?      */
  296.                   cp = strtok(cp,WHITESPACE); /* Yes --> Tokenize */
  297.  
  298.                *(tptr->loc) = strdup(cp); /* Save string          */
  299.                checkref( *(tptr->loc) );  /* Verify malloc()      */
  300.  
  301.             } /* else */
  302.          } /* else */
  303.  
  304.          if (!error)
  305.             tptr->bits |= B_FOUND;
  306.          return TRUE;         /* Report we found the keyword      */
  307.       } /* if (equal(buff, tptr->sym)) */
  308.    } /* for */
  309.  
  310. /*--------------------------------------------------------------------*/
  311. /*      We didn't find the keyword; report failure to the caller      */
  312. /*--------------------------------------------------------------------*/
  313.  
  314.    return FALSE;
  315.  
  316. } /* processconfig */
  317.  
  318. /*--------------------------------------------------------------------*/
  319. /*    g e t c o n f i g                                               */
  320. /*                                                                    */
  321. /*    Process a single configuration file                             */
  322. /*--------------------------------------------------------------------*/
  323.  
  324. boolean getconfig(FILE *fp,
  325.                   SYSMODE sysmode,
  326.                   CONFIGBITS program,
  327.                   CONFIGTABLE *table,
  328.                   FLAGTABLE *btable)
  329. {
  330.  
  331.    char buff[BUFSIZ];
  332.    char *cp;
  333.  
  334.    while(!(fgets(buff, sizeof buff, fp) == nil(char))) {
  335.  
  336.       if ((*buff == '\n') || (*buff == '#'))
  337.          continue;   /* comment line   */
  338.  
  339.       if (*(cp = buff + strlen(buff) - 1) == '\n')
  340.          *cp = '\0';
  341.  
  342.       if (!processconfig(buff,sysmode,program,table,btable))
  343.          printmsg(0,
  344.                "Unknown keyword \"%s\" in %s configuration file ignored",
  345.                buff, sysmode ? "system" : "user");
  346.  
  347.    } /*while*/
  348.  
  349.    return TRUE;
  350.  
  351. } /*getconfig*/
  352.  
  353. /*--------------------------------------------------------------------*/
  354. /*    o p t i o n s                                                   */
  355. /*                                                                    */
  356. /*    Process a line of boolean option flags.                         */
  357. /*--------------------------------------------------------------------*/
  358.  
  359. void options(char *s, SYSMODE sysmode , FLAGTABLE *flags, boolean *barray)
  360. {
  361.    char *token;
  362.  
  363.    strlwr(s);
  364.    token = strtok(s,WHITESPACE);
  365.  
  366.    while (token != NULL)
  367.    {
  368.       size_t subscript;
  369.       boolean hit = FALSE;
  370.       boolean negate;
  371.       negate = equaln(token,"no",2) && (strlen(token) > 2);
  372.  
  373.       for (subscript = 0; (subscript < F_LAST) && !hit; subscript++)
  374.       {
  375.          if ((flags[subscript].bits & B_GLOBAL) && (sysmode != SYSTEM_CONFIG))
  376.             continue;
  377.          if (negate)
  378.          {
  379.             if (equal(&token[2],flags[subscript].sym))
  380.             {
  381.                barray[ flags[subscript].position ] = FALSE;
  382.                hit = TRUE;
  383.             }
  384.          } /* if negate */
  385.          else {
  386.             if (equal(token,flags[subscript].sym))
  387.             {
  388.                barray[ flags[subscript].position ] = TRUE;
  389.                hit = TRUE;
  390.             }
  391.          } /* else */
  392.       } /* for */
  393.  
  394.       if (!hit)
  395.          printf("Invalid or system option '%s' specified\n",token);
  396.  
  397.       token = strtok(NULL,WHITESPACE);  /* Step to next token on line */
  398.  
  399.    } /* while */
  400. } /* options */
  401.  
  402. /*--------------------------------------------------------------------*/
  403. /*    c o n f i g u r e                                               */
  404. /*                                                                    */
  405. /*    Define the global parameters of UUPC/extended                   */
  406. /*--------------------------------------------------------------------*/
  407.  
  408. boolean configure( CONFIGBITS program)
  409. {
  410.    char *sysrc, *usrrc;
  411.    FILE *fp;
  412.    boolean success;
  413.  
  414.    CONFIGTABLE *tptr;
  415.  
  416.    if (!getrcnames(&sysrc, &usrrc))
  417.       return FALSE;
  418.  
  419. /*--------------------------------------------------------------------*/
  420. /*               Process the system configuration file                */
  421. /*--------------------------------------------------------------------*/
  422.  
  423.    if ((fp = FOPEN(sysrc, "r", TEXT)) == nil(FILE)) {
  424.       printmsg(0, "Cannot open system configuration file \"%s\"", sysrc);
  425.       printerr(sysrc);
  426.       return FALSE;
  427.    }
  428.    success = getconfig(fp, SYSTEM_CONFIG, program, table, configFlags);
  429.    fclose(fp);
  430.    if (!success)
  431.       return FALSE;
  432.  
  433. /*--------------------------------------------------------------------*/
  434. /*                Process the user configuration value                */
  435. /*--------------------------------------------------------------------*/
  436.  
  437.    if (usrrc != nil(char))
  438.    {
  439.       if ((fp = FOPEN(usrrc, "r", TEXT)) == nil(FILE)) {
  440.          printmsg(0, "Cannot open user configuration file \"%s\"", usrrc);
  441.          return FALSE;
  442.       }
  443.       success = getconfig(fp, USER_CONFIG, program, table, configFlags);
  444.       fclose(fp);
  445.       if (!success)
  446.          return FALSE;
  447.    }
  448.  
  449. /*--------------------------------------------------------------------*/
  450. /*          Validate that all required parameters were given          */
  451. /*--------------------------------------------------------------------*/
  452.  
  453.    for (tptr = table; tptr->sym != nil(char); tptr++) {
  454.       if ((tptr->bits & (B_REQUIRED | B_FOUND)) == B_REQUIRED)
  455.       {
  456.          printmsg(0, "%s configuration parameter \"%s\" must be set.",
  457.             (tptr->bits & B_GLOBAL) ? "System" : "User",
  458.             tptr->sym);
  459.          success = FALSE;
  460.       } /* if */
  461.    } /* for */
  462.  
  463.    return success;
  464.  
  465. } /*configure*/
  466.  
  467. /*--------------------------------------------------------------------*/
  468. /*    g e t r c n a m e s                                             */
  469. /*                                                                    */
  470. /*    Return the name of the configuration files                      */
  471. /*--------------------------------------------------------------------*/
  472.  
  473. #define  SYSRCSYM "UUPCSYSRC"
  474. #define USRRCSYM  "UUPCUSRRC"
  475. #define SYSDEBUG  "UUPCDEBUG"    /* Initialize debug level for UUPC  ahd   */
  476.  
  477. static boolean getrcnames(char **sysp,char **usrp)
  478. {
  479.    char *debugp = NULL;      /* Pointer to debug environment variable  */
  480.  
  481.    if ((*sysp = getenv(SYSRCSYM)) == nil(char))
  482.    {
  483.       printf("environment variable %s must be specified\n", SYSRCSYM);
  484.       return FALSE;
  485.    }
  486.  
  487.    *usrp = getenv(USRRCSYM);
  488.  
  489.    debugp = getenv(SYSDEBUG);
  490.  
  491.    if ( debugp != nil(char))        /* Debug specified in environment?     */
  492.       debuglevel = atoi(debugp);    /* Yes --> preset debuglevel for user  */
  493.  
  494.    return TRUE;
  495.  
  496. } /*getrcnames*/
  497.